iT邦幫忙

2022 iThome 鐵人賽

DAY 2
0
Modern Web

Parser 的深入研究系列 第 2

[Day02] - Parser 是什麼,可以吃嗎?

  • 分享至 

  • xImage
  •  

昨天說了很多次 Parser,但是那到底是是什麼呢?

其實 Parser 的其中一類就是將文字做解析的並將其轉換成 抽象語法樹(Abstract Syntax Tree,AST)的黑盒子函式。

打個比方,有個套件叫做 dotenv

他可以自動將 .env 檔案中的環境變數載入到 process.env 中。

使用如下 :

當我們有個 .env 檔案

# .env
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"

我們就會取到下述的資訊

require('dotenv').config();
console.log(process.env);
// { S3_BUCKET: 'YOURS3BUCKET', SECRET_KEY: 'YOURSECRETKEYGOESHERE' }

其實 require('dotenv').config() 內部執行了 3 個動作

  1. 讀取 .env 檔案
  2. 將 .env 檔案內容轉換成 AST ( Parser )
  3. 將 AST 資訊放入 process.env 中

拆開來大概如下的感覺 ,

const dotenv = require('dotenv');
const fs = require('fs');

// 1. 讀取 .env 檔案
const properties = fs.readFileSync('.env').toString();

// 2. 將 .env 檔案內容轉換成 AST ( Parser )
const parsed = dotenv.parse(properties);

// 3. 將 AST 資訊放入 process.env 中
Object.keys(parsed).forEach(key => process.env[key] = parsed[key]);

// 4. 檢查 process.env 是否有 .env 的資料
console.log('process.env=', process.env);

第二步 , 就是所謂的 Parser ,

也就是說 , 文字經過 Parser 後 , 會變成一個 Object ( 我們可稱之為 AST )

明天我們就來更進一步的了解 dotenv 是如何將 .env 內的文字轉換成 AST 的。


感謝 lagagain 的補充 <(_ _)>,
Parser 函式的輸出結果不一定是 AST 也可以是 CST 或是 Byte Code
本文用詞不精準,應該說有一類的 Parser 會輸入文字 - 輸出 AST

上一篇
[Day01] - 參賽的起因 & 研究的動機
下一篇
[Day03] - .env 規則說明與解析準備
系列文
Parser 的深入研究32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
carternolan
iT邦新手 5 級 ‧ 2022-09-18 10:17:11

Dotenv有parse的功能
但是拿Dotenv parse 後的結果當成是 AST 不是很妥當

維基上面對於AST的解說與應用有提到

It often serves as an intermediate representation of the program through several stages that the compiler requires

Dotenv parse後的object基本上就直接餵給 process.env 了,並沒有什麼再有什麼特殊的處理了

看更多先前的回應...收起先前的回應...
Tree iT邦新手 3 級 ‧ 2022-09-18 20:41:56 檢舉

感謝 carternolan 的留言分享

筆者目前所知,只要是 Parsed Tree 都可以算是 AST 的一種

AST 也確實常跟 compiler 一起使用,不過 AST 不一定只能跟 compiler 使用吧 /images/emoticon/emoticon19.gif

筆者目前所知,只要是 Parsed Tree 都可以算是 AST 的一種

想請問有這個資料的資料來源嗎

從中文 wiki看到的資料是

和抽象語法樹相對的是具體語法樹(通常稱作分析樹)

就與作者提到的有所衝突了
不曉得作者對於 AST 的定義為何?

lagagain iT邦新手 2 級 ‧ 2022-09-18 22:33:29 檢舉

抽象語法樹相對應的是具體語法樹(Concrete Syntax Tree, CST),也叫做解析樹(Parse Tree,或者Parsing Tree)。
-- 自己動手實現Lua

得說我比較認同 carternolan 所說的...

將文字解析成電腦或程式容易處理的格式或物件的過程,稱之為Parsing這沒什麼問題,其結果不一定都是叫做AST,有可能AST只是其中一個過程而已。
何況...下面結果實在感覺不出有樹(Tree)的樣子

{
  "S3_BUCKET": "YOURS3BUCKET",
  "SECRET_KEY": "YOURSECRETKEYGOESHERE"
}

以原始來源

# .env
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"

CST可能被處理成

+ `<root>`
|-- "# .env" (token type: comment)
|
|-+ `<key pair>`
| |-- "S3_BUCKET" (token type: key)
| |--"="
| |--"YOURS3BUCKET" (token type: value)
|
|-+ `<key pair>`
| |-- "SECRET_KEY" (token type: key)
| |-- "="
| |-- "YOURSECRETKEYGOESHERE" (token type: value)

節點(node)可能帶有一些屬性,是後續處理上可能會使用到的。像是上例comment和"="的節點在處理上作用不大,可以被忽略,才變成抽象語法樹(AST)

+ `<root>`
|-+ `<key pair>`
| |-- "S3_BUCKET" (token type: key)
| |--"YOURS3BUCKET" (token type: value)
|
|-+ `<key pair>`
| |-- "SECRET_KEY" (token type: key)
| |-- "YOURSECRETKEYGOESHERE" (token type: value)
Tree iT邦新手 3 級 ‧ 2022-09-19 05:31:18 檢舉

目前想要統一 30 天文章 Parse 結果有一個固定的名稱

所以可能結果要叫 ST ( Syntax Tree ) 比較妥當嗎 ? /images/emoticon/emoticon19.gif

非本科 , 研究 Parse 有些名稱比較不精準 , 可能要請多多包涵 /images/emoticon/emoticon41.gif

Tree iT邦新手 3 級 ‧ 2022-09-19 13:10:45 檢舉

整理一下邦友 carternolan lagagain 提到的幾個點,我分享一下個人觀點

  • Q. 後續沒有用 compiler 的不算是 AST
    [個人觀點] 目前 Vue Runtime 的流程是
(string)--tokenizer-->(tokens)--parser-->(AST)--render--> (HTML DOM)

所以 AST 應該不用必定跟 compiler 一同出現


  • Q. envdot parse 出來的結果算不算 Tree
    [個人觀點] 根據 Tree 的定義 , 他是其中一種沒錯 , 雖然單層感覺不像 Tree

Tree represents the nodes connected by edges

所以 AST 應該不用必定跟 compiler 一同出現

貼那段的意思重點在於 AST 是 intermediate representation
算是一個中間階段,當然並沒有一定要compiler一起使用

個人觀點的話是覺得作者寫出來的東西能夠對於讀者負責,希望用詞能夠更精準,而不是自己覺得很好就拿來使用,也不是用了一句非本科,請多包涵來帶過

Tree 大大加油

Tree iT邦新手 3 級 ‧ 2022-09-20 07:47:50 檢舉

作者寫出來的東西能夠對於讀者負責,希望用詞能夠更精準,而不是自己覺得很好就拿來使用,也不是用了一句非本科,請多包涵來帶過

這點我非常同意,不過非本科真的需要 邦友 幫忙科普,因為網路上關於 AST 的文章有些有誤,而作者又沒有能力鑑別錯誤 (:з」∠)

感謝 carternolan 的指教 /images/emoticon/emoticon41.gif

我要留言

立即登入留言